package com.nanuminc.market.mapsearch;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.nanuminc.market.NMConstants;
import com.nanuminc.market.R;
import com.nanuminc.market.utils.DomParserUtil;
import com.nanuminc.market.utils.XMLUtil;

public class MyMapSearch extends MapActivity {

	MapView mapView;
	MapController mc;
	List<Overlay> overlay;
	String mProvider;
	String locXml;
	/** Google에서 현재 주소 가져오는 xml */
	String currentAddress;
	/** 현재위치 주소 */

	Drawable mMappin;
	Location currentLocation; // 현재 위치
	LocationManager mLocMan;
	MyLocationOverlay2 mLocation;

	GeoPoint currentGP;
	/** 현재좌표 지오포인터 */

	DomParserUtil parser = new DomParserUtil();
	/** dom parser */

	int totalListNum;
	static double currentLatitude, currentLongitude;
	/** 현재위치 좌표 */

	/** 맵에 표시된 오버레이를 가지고있는 리스트. */
	List<Overlay> listOverlays;

	/** 맵핀 선택시 풍선도움말 띄워주기위함 */
	private BalloonOverlayView balloonView;

	ArrayList<String> nm_title_array = new ArrayList<String>();
	ArrayList<String> nm_contants_array = new ArrayList<String>();
	ArrayList<String> nm_latitude_array = new ArrayList<String>();
	ArrayList<String> nm_longitude_array = new ArrayList<String>();
	ArrayList<String> nm_pid_array = new ArrayList<String>();

	TextView title_left, title_center, title_right;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.mymapsearch);

		title_left = (TextView) findViewById(R.id.btn_location);
		title_center = (TextView) findViewById(R.id.btn_title);
		title_right = (TextView) findViewById(R.id.btn_search);
		title_left.setVisibility(View.INVISIBLE);
		title_right.setVisibility(View.VISIBLE);
		title_center.setVisibility(View.VISIBLE);
		
		mapView = (MapView) findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true); // 줌기능 제공여부
		mapView.setSatellite(false); // 위성지도 사용여부 true면 위성지도
		mLocMan = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

		// 사용가능한 적절한 프로바이더를 받아온다.
		// network (보통 3G망,Wifi AP 위치정보)또는 gps 둘중 하나로 설정된다.
		mProvider = mLocMan.getBestProvider(new Criteria(), true);
		currentLocation = mLocMan.getLastKnownLocation(mProvider);

		mc = mapView.getController();
		mc.setZoom(17);

		mLocation = new MyLocationOverlay2(this, mapView);

		mLocMan.requestLocationUpdates(mProvider, 2, 3, mLocationListener);

		updateOverlay(currentLocation);
	}

	protected void updateOverlay(Location location) {
		if (location != null) {
			currentGP = new GeoPoint((int) (location.getLatitude() * 1000000),
					(int) (location.getLongitude() * 1000000));

			currentLatitude = location.getLatitude();
			currentLongitude = location.getLongitude();

			locXml = XMLUtil.getXml("http://maps.google.co.kr/maps/geo?q="
					+ currentLatitude + "," + currentLongitude
					+ "&output=xml&sensor=false&key=");

			// dom parser
			currentAddress = parser
					.getNode(0, parser.getNodeList(
							parser.getDomElement(locXml), "address"));
			Log.e("nanum", "현재위치 : " + currentAddress);

			/** 현재위치 overlay add */
			Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
					R.drawable.icon_mypoint);
			// bitmap = Bitmap.createScaledBitmap(bitmap, 50, 50, false);
			Drawable drawable = new BitmapDrawable(bitmap);
			MyIconItemizedOverlay mdio = new MyIconItemizedOverlay(drawable);
			OverlayItem overlayitem = new OverlayItem(currentGP, "", "");
			mdio.addOverlayItem(overlayitem);
			overlay = mapView.getOverlays();
			overlay.add(mdio);
		}
	}

	/*
	 * 주변검색
	 * 
	 * search : 검색어 null이면 일반.
	 */
	public void LocalAreaSearch(String search) {
		locXml = NMConstants.LOCAL_SEARCH_URL;

		// dom parser
		Element elem = parser.getDomElement(locXml);
		NodeList nm_conts_node = parser.getNodeList(elem, "pid");
		totalListNum = nm_conts_node.getLength();

		mMappin = getResources().getDrawable(R.drawable.mappin);
		mMappin.setBounds(0, 0, mMappin.getIntrinsicWidth(),
				mMappin.getIntrinsicHeight());

		for (int index = 0; index < totalListNum; index++) {
			nm_pid_array.add(parser.getNode(index,
					parser.getNodeList(elem, "pid")));
			nm_title_array.add(parser.getNode(index,
					parser.getNodeList(elem, "title")));
			nm_contants_array.add(parser.getNode(index,
					parser.getNodeList(elem, "contents")));
			nm_latitude_array.add(parser.getNode(index,
					parser.getNodeList(elem, "latitude")));
			nm_longitude_array.add(parser.getNode(index,
					parser.getNodeList(elem, "longitude")));
		}

		SearchOverlay mSerchview = new SearchOverlay(mMappin);
		listOverlays.add(mSerchview);
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	protected void onResume() {
		super.onResume();
	}

	LocationListener mLocationListener = new LocationListener() {

		public void onStatusChanged(String provider, int status, Bundle extras) {
			String sStatus = "";
			switch (status) {
			case LocationProvider.OUT_OF_SERVICE:
				sStatus = "범위 벗어남";
				break;
			case LocationProvider.TEMPORARILY_UNAVAILABLE:
				sStatus = "일시적 불능";
				break;
			case LocationProvider.AVAILABLE:
				sStatus = "사용 가능";
				break;
			}
			Log.e("hyup2", provider + "상태변경 :" + sStatus);

		}

		public void onProviderEnabled(String provider) {
		}

		public void onProviderDisabled(String provider) {
		}

		public void onLocationChanged(Location location) {
		}
	};

	@Override
	public void onDestroy() {
		super.onDestroy();
		LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		lm.removeUpdates(mLocationListener);
	}

	class MyLocationOverlay2 extends MyLocationOverlay {
		public MyLocationOverlay2(Context context, MapView mapView) {
			super(context, mapView);
			// TODO Auto-generated constructor stub
		}
	}

	class SearchOverlay extends ItemizedOverlay<OverlayItem> {
		private View clickRegion;
		private int viewOffset;
		final MapController mc;

		public SearchOverlay(Drawable defaultMarker) {
			super(defaultMarker);
			// 마커 이미지의 가운데 아랫부분이 마커에서 표시하는 포인트가 되게 한다.
			viewOffset = 0;
			mc = mapView.getController();
			boundCenterBottom(defaultMarker);
			boundCenter(mMappin);
			populate();
		}

		protected boolean onBalloonTap(int index) {
			hideBalloon();
			return true;
		}

		public void setBalloonBottomOffset(int pixels) {
			viewOffset = pixels;
		}

		@Override
		protected OverlayItem createItem(int i) {

			OverlayItem item = null;

			item = new OverlayItem(currentGP, nm_title_array.get(i),
					nm_contants_array.get(i));
			return item;
		}

		/**
		 * return value = 맵뷰에 표시될 갯수에따라 달라짐
		 */
		@Override
		public int size() {
			return totalListNum;
		}

		private void hideBalloon() {
			if (balloonView != null) {
				balloonView.setVisibility(View.GONE);
			}
		}

		private void hideOtherBalloons(List<Overlay> overlays) {
			for (Overlay overlay : overlays) {
				hideBalloon();
			}
		}

		public boolean onTap(int index) {

			boolean isRecycled;
			final int thisIndex;
			GeoPoint point;

			thisIndex = index;
			point = createItem(index).getPoint();

			if (balloonView == null) {
				balloonView = new BalloonOverlayView(mapView.getContext(),
						viewOffset);
				clickRegion = (View) balloonView
						.findViewById(R.id.balloon_inner_layout);
				isRecycled = false;
			} else {
				isRecycled = true;
			}

			balloonView.setVisibility(View.GONE);

			List<Overlay> mapOverlays = mapView.getOverlays();
			if (mapOverlays.size() > 1) {
				hideOtherBalloons(mapOverlays);
			}

			balloonView.setData(createItem(index));

			MapView.LayoutParams params = new MapView.LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
					point, MapView.LayoutParams.BOTTOM_CENTER);
			params.mode = MapView.LayoutParams.MODE_MAP;

			setBalloonTouchListener(thisIndex);

			balloonView.setVisibility(View.VISIBLE);

			if (isRecycled) {
				balloonView.setLayoutParams(params);
			} else {
				mapView.addView(balloonView, params);
			}
			mc.animateTo(point);
			return true;
		}

		private void setBalloonTouchListener(final int thisIndex) {

			try {
				@SuppressWarnings("unused")
				Method m = this.getClass().getDeclaredMethod("onBalloonTap",
						int.class);
				if (clickRegion == null)
					clickRegion = (View) balloonView
							.findViewById(R.id.balloon_inner_layout);
				clickRegion.setOnTouchListener(new OnTouchListener() {
					public boolean onTouch(View v, MotionEvent event) {

						View l = ((View) v.getParent())
								.findViewById(R.id.balloon_main_layout);
						Drawable d = l.getBackground();

						if (event.getAction() == MotionEvent.ACTION_DOWN) {
							int[] states = { android.R.attr.state_pressed };
							if (d.setState(states)) {
								d.invalidateSelf();
							}
							return true;
						} else if (event.getAction() == MotionEvent.ACTION_UP) {
							int newStates[] = {};
							if (d.setState(newStates)) {
								d.invalidateSelf();
							}
							// call overridden method
							onBalloonTap(thisIndex);
							return true;
						} else {
							return false;
						}

					}
				});

			} catch (SecurityException e) {
				Log.e("BalloonItemizedOverlay",
						"setBalloonTouchListener reflection SecurityException");
				return;
			} catch (NoSuchMethodException e) {
				// method not overridden - do nothing
				return;
			}

		}

		@Override
		public boolean onTouchEvent(MotionEvent event, MapView mapView) {
			// TODO Auto-generated method stub

			return super.onTouchEvent(event, mapView);
		}

	}
}
